Categories
Quasar

Developing Vue Apps with the Quasar Library — Touch Pan Directive

Spread the love

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

Touch Pan Directive

We can listen to touch pan events with the v-touch directive.

For example, we can write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md">
        <q-card
          v-touch-pan.prevent.mouse="handlePan"
          class="custom-area cursor-pointer bg-primary text-white shadow-2 relative-position row flex-center"
        >
          <div v-if="info" class="custom-info">
            <pre>{{ info }}</pre>
          </div>
          <div v-else class="text-center">
            <q-icon name="arrow_upward"></q-icon>
            <div class="row items-center">
              <q-icon name="arrow_back"></q-icon>
              <div>Pan in any direction</div>
              <q-icon name="arrow_forward"></q-icon>
            </div>
            <q-icon name="arrow_downward"></q-icon>
          </div>

          <div v-show="panning" class="touch-signal">
            <q-icon name="touch_app"></q-icon>
          </div>
        </q-card>
      </div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          info: null,
          panning: false
        },
        methods: {
          handlePan({ evt, ...info }) {
            this.info = info;
            if (info.isFirst) {
              this.panning = true;
            } else if (info.isFinal) {
              this.panning = false;
            }
          }
        }
      });
    </script>
  </body>
</html>

We add the v-touch-pan directive to the element we want to watch the touch and pan events for.

Then we get the event info from the first parameter of the event listener.

We get the distance, duration, offset, position, and more with the parameter.

isFirst indicates whether it’s the start of mouse drag or touch pan.

And isFinal indicates whether it’s the end of the mouse drag or touch pan.

We can restrict the direction of panning that’s detected for horizontal directions only with the horizontal modifier:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md">
        <q-card
          v-touch-pan.horizontal.prevent.mouse="handlePan"
          class="custom-area cursor-pointer bg-primary text-white shadow-2 relative-position row flex-center"
        >
          <div v-if="info" class="custom-info">
            <pre>{{ info }}</pre>
          </div>
          <div v-else class="text-center">
            <div class="row items-center">
              <q-icon name="arrow_back"></q-icon>
              <div>Pan left or right</div>
              <q-icon name="arrow_forward"></q-icon>
            </div>
          </div>

          <div v-show="panning" class="touch-signal">
            <q-icon name="touch_app"></q-icon>
          </div>
        </q-card>
      </div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          info: null,
          panning: false
        },
        methods: {
          handlePan({ evt, ...info }) {
            this.info = info;
            if (info.isFirst) {
              this.panning = true;
            } else if (info.isFinal) {
              this.panning = false;
            }
          }
        }
      });
    </script>
  </body>
</html>

Also, we can change the modifier to vertical to watch up and downward panning only:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md">
        <q-card
          v-touch-pan.vertical.prevent.mouse="handlePan"
          class="custom-area cursor-pointer bg-primary text-white shadow-2 relative-position row flex-center"
        >
          <div v-if="info" class="custom-info">
            <pre>{{ info }}</pre>
          </div>
          <div v-else class="text-center">
            <div class="row items-center">
              <div>Pan up or down</div>
            </div>
          </div>

          <div v-show="panning" class="touch-signal">
            <q-icon name="touch_app"></q-icon>
          </div>
        </q-card>
      </div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          info: null,
          panning: false
        },
        methods: {
          handlePan({ evt, ...info }) {
            this.info = info;
            if (info.isFirst) {
              this.panning = true;
            } else if (info.isFinal) {
              this.panning = false;
            }
          }
        }
      });
    </script>
  </body>
</html>

Conclusion

We can watch touch pan events with the v-touch-pan directive.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *